package com.lsy.seckill.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lsy.seckill.mapper.SeckillGoodsMapper;
import com.lsy.seckill.mapper.SeckillOrderMapper;
import com.lsy.seckill.pojo.*;
import com.lsy.seckill.service.OrderService;
import com.lsy.seckill.mapper.OrderMapper;
import com.lsy.seckill.vo.SeckillGoodsVo;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
* @author 19040
* @description 针对表【t_order】的数据库操作Service实现
* @createDate 2024-09-15 11:54:48
*/
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order>
    implements OrderService{
    @Resource
    private SeckillGoodsMapper seckillGoodsMapper;
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private SeckillOrderMapper seckillOrderMapper;
    @Resource
    private RedisTemplate redisTemplate;
    @Override
    @Transactional
    public Order seckill(User user,SeckillGoodsVo seckillGoodsVo) {
        Long seckillGoodsId = seckillGoodsVo.getId();
        SeckillGoods seckillGoods = seckillGoodsMapper.selectById(seckillGoodsId);
        Integer stockCount = seckillGoods.getStockCount();

        //老师分析
        //1. Mysql在默认的事务隔离级[REPEATABLE-READ]别下
        //2. 执行update语句时,会在事务中锁定要更新的行
        //3. 这样可以防止其它会话在同一行执行update,delete
        UpdateWrapper<SeckillGoods> wrapper = new UpdateWrapper<SeckillGoods>().eq("goods_id", seckillGoodsId)
                .set("stock_count", stockCount - 1).gt("stock_count",0);
        int update = seckillGoodsMapper.update(seckillGoods, wrapper);
        if (update<=0){
            //没库存了
            return null;
        }
        Order order = new Order();
        order.setId(null);
        order.setUserId(user.getId());
        order.setGoodsId(seckillGoodsId);
        order.setDeliveryAddrId(0L);
        order.setGoodsName(seckillGoodsVo.getGoodsName());
        order.setGoodsCount(1);
        order.setGoodsPrice(seckillGoodsVo.getGoodsPrice());
        order.setOrderChannel(1);
        order.setStatus(0);
        order.setCreateDate(new Date());
        orderMapper.insert(order);

        //生成秒杀商品订单-
        SeckillOrder seckillOrder = new SeckillOrder();
        seckillOrder.setGoodsId(seckillGoodsVo.getId());
        //这里秒杀商品订单对应的order_id 是从上面你添加 order后获取到的
        seckillOrder.setOrderId(order.getId());
        seckillOrder.setUserId(user.getId());

        seckillOrderMapper.insert(seckillOrder);

        //将生成的秒杀订单，存入到Redis, 这样在查询某个用户是否已经秒杀了这个商品时，
        //直接到Redis中查询，起到优化效果
        //设计秒杀订单的key => order:用户id:商品id
        redisTemplate.opsForValue()
                .set("order:" + user.getId() + ":" + seckillGoodsVo.getId(), seckillOrder);

        return order;
    }
}




